using Single.Core.Service;
using Single.Sugar.Service;
using Single.Sys.Entity;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Text;

namespace Single.Sys.Service
{
    public class SysMenuFunctionService : BaseService<SysMenuFunction>
    {
        public List<SysMenuFunction> GetByMenuId(long id)
        {
            var query = rep.AsQueryable().OrderBy(m => m.Sequence, SqlSugar.OrderByType.Asc);

            return query.Where(m => m.MenuId.Equals(id)).ToList();
        }

        public ServiceResult Assign(long menuId, List<SysMenuFunction> rows)
        {
            var oldList = rep.AsQueryable().Where(m => m.MenuId.Equals(menuId)).OrderBy(m => m.Sequence, SqlSugar.OrderByType.Asc).ToList();

            var iList = new List<SysMenuFunction>();
            var uList = new List<SysMenuFunction>();

            for (var i = 0; i < rows.Count; i++)
            {
                var obj = rows[i]; obj.Sequence = i;
                var old = oldList.FirstOrDefault(m => m.Id.Equals(obj.Id));
                if (old != null) { obj.Id = old.Id; uList.Add(obj); } else { obj.Id = 0; iList.Add(obj); }
            }

            var dList = new List<SysMenuFunction>();

            oldList.ForEach(m =>
            {
                if (!rows.Any(n => n.Id.Equals(m.Id))) { dList.Add(m); }
            });

            var result = tenant.UseTran(() =>
            {
                rep.InsertRange(iList); rep.UpdateRange(uList); rep.Delete(dList);
            });

            return UnknownResult(result.IsSuccess);
        }

        public override List<SysMenuFunction> GetAll()
        {
            return rep.AsQueryable().OrderBy(m => m.Sequence, SqlSugar.OrderByType.Asc).ToList();
        }

        public List<SysMenuFunction> GetByUserId(long menuId, long userId, bool isSuper)
        {
            var query = rep.AsQueryable().Where(mf => mf.MenuId.Equals(menuId));

            if (!isSuper)
            {
                query = query.InnerJoin<SysRoleMenuFunction>((mf, rmf) => mf.Id == rmf.MenuFunctionId)
                    .InnerJoin<SysUserRole>((mf, rmf, ur) => rmf.RoleId == ur.RoleId)
                    .InnerJoin<SysRole>((mf, rmf, ur, r) => ur.RoleId == r.Id)
                    .Where((mf, rmf, ur, r) => ur.UserId == userId && r.Status.Equals("ok"));
            }

            return query.OrderBy(mf => mf.Sequence, SqlSugar.OrderByType.Asc).ToList();
        }

        public SysMenuFunction GetChildByUserId(long menuId, string src, long userId, bool isSuper)
        {
            var query = rep.AsQueryable().Where(m => m.SysMenu.Pid == menuId && m.SysMenu.Type == "child" && m.SysMenu.Src == src);

            if (!isSuper)
            {
                query = query.InnerJoin<SysRoleMenuFunction>((mf, rmf) => mf.Id == rmf.MenuFunctionId)
                    .InnerJoin<SysUserRole>((mf, rmf, ur) => rmf.RoleId == ur.RoleId)
                    .InnerJoin<SysRole>((mf, rmf, ur, r) => ur.RoleId == r.Id)
                    .Where((mf, rmf, ur, r) => ur.UserId == userId && r.Status.Equals("ok"));
            }

            return query.OrderBy(mf => mf.Sequence, SqlSugar.OrderByType.Asc).First();
        }
    }
}